#include "ComboState.h"
#include <iostream>

using namespace std;

const char* button_name[10]
  = {
	    "North"
	  , "Northeast"
	  , "East"
	  , "Southeast"
	  , "South" 
	  , "Southwest"
	  , "West"
	  , "Northwest"
	  , "Punch"
	  , "Kick"
	};

/******************************************************************************
* Implement the ComboState default constructor.
* Set ALL member pointers to 0.
******************************************************************************/
  ComboState::ComboState(Button move,Button attack) : move(move),attack(attack)
  {

  }
/******************************************************************************
* Implement the ComboState copy constructor.
* Deep-copy only those pointers that point to actual objects.
******************************************************************************/
  ComboState::ComboState(ComboState const& combo)
  {

  }
/******************************************************************************
* Implement the ComboState assignment operator.
* Deep-copy only those pointers that point to actual objects.
* Make sure you free any dynamic memory that doesn't belong.
******************************************************************************/

/******************************************************************************
* Implement the ComboState destructor.
* Free ALL dynamic memory.
******************************************************************************/

bool ComboState::has_no_next_state(Button b) 
{
	return !_next_state[b];
}

ComboState* ComboState::get_next_state(Button b)
{
	if (has_no_next_state(b))
	{
		_next_state(b) = new ComboState(move,attack);
	}

	return _next_state[b];
}

ComboState::~ComboState()
{

}

const char* ComboState::get_name() const
{
	return name;
}

void ComboState::set_name(const char* name)
{
	_clear_name();

	if (name)
	{
		name = new char[strlen(name) + 1];
		strcpy_s(name, strlen(name) + 1, name);
	}
}

void ComboState::_clear_name()
{
	if (name)
	{
		delete[] name;
		name = 0;
	}
}

ostream& operator<<(ostream& os, const ComboState& state)
{
	if (state.name)
	{
		os << state.name << endl;
	}

	for (unsigned int b = 0; b < ComboState::COUNT; ++b)
	{
		if (state._next_state(b))
		{
			os << name << '+' << *(state._next_state[b]);
		}
	}

	return os << '-';
}

void Charger(ComboState* start_state)
{
	start_state->get_next_state(ComboState::SE)->get_next_state(ComboState::N)
		->get_next_state(ComboState::KICK)->set_name("Left Crescent Kick");
	start_state->get_next_state(ComboState::SW)->get_next_state(ComboState::N)
		->get_next_state(ComboState::KICK)->set_name("Right Crescent Kick");
	start_state->get_next_state(ComboState::SE)->get_next_state(ComboState::W)
		->get_next_state(ComboState::PUNCH)->set_name("Left Firedisc");
	start_state->get_next_state(ComboState::SW)->get_next_state(ComboState::E)
		->get_next_state(ComboState::PUNCH)->set_name("Right Firedisc");
}

void Masher(ComboState* start_state)
{
	start_state->get_next_state(ComboState::W)
		->get_next_state(ComboState::KICK)
		->get_next_state(ComboState::KICK)->set_name("Left 100 Feet");
	start_state->get_next_state(ComboState::E)
		->get_next_state(ComboState::KICK)
		->get_next_state(ComboState::KICK)->set_name("Right 100 Feet");
	start_state->get_next_state(ComboState::W)
		->get_next_state(ComboState::PUNCH)
		->get_next_state(ComboState::PUNCH)->set_name("Left 100 Hands");
	start_state->get_next_state(ComboState::E)
		->get_next_state(ComboState::PUNCH)
		->get_next_state(ComboState::PUNCH)->set_name("Right 100 Hands");
}

void Shotokan(ComboState* start_state)
{
	start_state->get_next_state(ComboState::S)->get_next_state(ComboState::SW)
		->get_next_state(ComboState::W)->get_next_state(ComboState::PUNCH)
		->set_name("Left Fireball");
	start_state->get_next_state(ComboState::S)->get_next_state(ComboState::SE)
		->get_next_state(ComboState::E)->get_next_state(ComboState::PUNCH)
		->set_name("Right Fireball");
	start_state->get_next_state(ComboState::S)->get_next_state(ComboState::SE)
		->get_next_state(ComboState::E)->get_next_state(ComboState::KICK)
		->set_name("Left Helo Kick");
	start_state->get_next_state(ComboState::S)->get_next_state(ComboState::SW)
		->get_next_state(ComboState::W)->get_next_state(ComboState::KICK)
		->set_name("Right Helo Kick");
}

int main()
{
	/**************************************************************************
	* Create a function pointer array of size 3
	* and a ComboState array of size 4.
	*
	* Each element in the function pointer array should point to
	* a function whose single argument is a ComboState pointer and
	* whose return type is void.
	*
	* We have provided three such functions for you.
	* Invoke one for each of the first 3 elements in the ComboState array
	* using the corresponding function pointer.
	**************************************************************************/

	/**************************************************************************
	* To test the assignment operator, set the 4th element equal to the 1st.
	* Send the result to standard output.  Do this all in one statement.
	**************************************************************************/

	/**************************************************************************
	* To test the copy constructor, create a separate ComboState
	* that is a copy of the 2nd element in the array.
	* Send this new object to standard output.
	**************************************************************************/

	/**************************************************************************
	* Free ALL dynamic memory.
	**************************************************************************/
}
